<template>
  <div class="markdown-editor" :class="{ 'fullscreen': isFullscreen }">
    <div class="editor-toolbar">
      <div class="toolbar-left">
        <el-button-group>
          <el-button size="small" @click="togglePreview" :title="isPreview ? '切换到编辑模式' : '切换到预览模式'">
            <el-icon><View /></el-icon>
            {{ isPreview ? '编辑' : '预览' }}
          </el-button>
          <el-button size="small" @click="toggleFullscreen" :title="isFullscreen ? '退出全屏 (ESC)' : '页面全屏'">
            <el-icon><FullScreen /></el-icon>
            {{ isFullscreen ? '退出全屏' : '全屏' }}
          </el-button>
        </el-button-group>
      </div>
      
      <div class="toolbar-center">
        <el-button-group>
          <el-button size="small" @click="insertBold" title="粗体">
            <strong>B</strong>
          </el-button>
          <el-button size="small" @click="insertItalic" title="斜体">
            <em>I</em>
          </el-button>
          <el-button size="small" @click="insertCode" title="代码">
            <el-icon><Code /></el-icon>
          </el-button>
          <el-button size="small" @click="insertQuote" title="引用块（带背景）">
            <el-icon><ChatLineRound /></el-icon>
          </el-button>
          <el-button size="small" @click="insertLink" title="链接">
            <el-icon><Link /></el-icon>
          </el-button>
          <el-button size="small" @click="insertImage" title="图片">
            <el-icon><Picture /></el-icon>
          </el-button>
        </el-button-group>
        
        <el-button-group>
          <el-button size="small" @click="insertUnorderedList" title="无序列表">
            <el-icon><List /></el-icon>
          </el-button>
          <el-button size="small" @click="insertOrderedList" title="有序列表">
            <el-icon><Sort /></el-icon>
          </el-button>
          <el-button size="small" @click="insertTable" title="表格">
            <el-icon><Grid /></el-icon>
          </el-button>
          <el-button size="small" @click="insertTextIndent" title="文本缩进">
            <strong>&gt;</strong>
          </el-button>
          <el-button size="small" @click="removeTextIndent" title="移除缩进">
            <strong>&lt;</strong>
          </el-button>
        </el-button-group>
      </div>
      
      <div class="toolbar-right">
        <el-button size="small" @click="toggleLivePreview">
          <el-icon><Monitor /></el-icon>
          {{ showLivePreview ? '关闭预览' : '实时预览' }}
        </el-button>
      </div>
    </div>
    
    <div class="editor-content" :class="{ 'preview-mode': isPreview, 'live-preview': showLivePreview }" @drop="handleDrop" @dragover="handleDragOver" @dragenter="handleDragEnter" @dragleave="handleDragLeave">
      <div v-if="!isPreview" class="editor-panel">
        <textarea
          ref="textareaRef"
          v-model="content"
          class="editor-textarea"
          :class="{ 'drag-over': isDragOver }"
          placeholder="开始编写您的文章..."
          @input="handleInput"
          @keydown="handleKeyDown"
        ></textarea>
        <div v-if="isDragOver" class="drag-overlay">
          <div class="drag-message">
            <el-icon size="48"><Upload /></el-icon>
            <p>拖拽图片到此处上传</p>
          </div>
        </div>
      </div>
      
      <div v-if="isPreview || showLivePreview" class="preview-panel">
        <div class="preview-content" v-html="previewHtml"></div>
      </div>
    </div>
    
    <div class="editor-footer">
      <div class="word-count">
        字数: {{ wordCount }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import api from '@/utils/api'
import { ElMessage } from 'element-plus'

// 配置marked
marked.setOptions({
  highlight: function(code: string, lang: string) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(code, { language: lang }).value
      } catch (err) {
        console.error(err)
      }
    }
    return hljs.highlightAuto(code).value
  },
  breaks: true,
  gfm: true
} as any)

const props = defineProps<{
  modelValue: string
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const textareaRef = ref<HTMLTextAreaElement>()
const isPreview = ref(false)
const showLivePreview = ref(false)
const isFullscreen = ref(false)
const isDragOver = ref(false)
const content = ref(props.modelValue)

const wordCount = computed(() => {
  return content.value.length
})

const previewHtml = computed(() => {
  return marked(content.value)
})

const handleInput = () => {
  emit('update:modelValue', content.value)
}

const togglePreview = () => {
  isPreview.value = !isPreview.value
  showLivePreview.value = false
}

const toggleLivePreview = () => {
  showLivePreview.value = !showLivePreview.value
  isPreview.value = false
}

const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value
  // 不需要调用浏览器的全屏API，只需要切换CSS类即可
}

const insertImage = async () => {
  // 创建文件输入元素
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/*'
  input.style.display = 'none'
  
  input.onchange = async (event) => {
    const file = (event.target as HTMLInputElement).files?.[0]
    if (!file) return
    
    // 检查文件大小（5MB限制）
    if (file.size > 5 * 1024 * 1024) {
      ElMessage.error('图片文件大小不能超过5MB')
      return
    }
    
    // 检查文件类型
    if (!file.type.startsWith('image/')) {
      ElMessage.error('请选择图片文件')
      return
    }
    
    try {
      // 创建FormData
      const formData = new FormData()
      formData.append('file', file)
      
      // 上传图片
      const response = await api.post('/posts/upload-image', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      })
      
      // 插入图片到编辑器
      const imageUrl = response.data.url
      // 直接使用默认描述，用户可以后续修改
      insertText(`![图片描述](${imageUrl})\n`)
      
      ElMessage.success('图片上传成功')
    } catch (error) {
      console.error('图片上传失败:', error)
      ElMessage.error('图片上传失败，请重试')
    }
  }
  
  // 触发文件选择
  document.body.appendChild(input)
  input.click()
  document.body.removeChild(input)
}

// 拖拽处理函数
const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
}

const handleDragEnter = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = true
}

const handleDragLeave = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  // 只有当拖拽离开整个编辑器区域时才隐藏拖拽提示
  if (!(e.currentTarget as Node)?.contains(e.relatedTarget as Node)) {
    isDragOver.value = false
  }
}

const handleDrop = async (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = false
  
  const files = e.dataTransfer?.files
  if (!files || files.length === 0) return
  
  const file = files[0]
  
  // 检查文件类型
  if (!file.type.startsWith('image/')) {
    ElMessage.error('请拖拽图片文件')
    return
  }
  
  // 检查文件大小
  if (file.size > 5 * 1024 * 1024) {
    ElMessage.error('图片文件大小不能超过5MB')
    return
  }
  
  try {
    const formData = new FormData()
    formData.append('file', file)
    
    const response = await api.post('/posts/upload-image', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
    
    const imageUrl = response.data.url
    // 直接使用默认描述，用户可以后续修改
    insertText(`![图片描述](${imageUrl})\n`)
    
    ElMessage.success('图片上传成功')
  } catch (error) {
    console.error('图片上传失败:', error)
    ElMessage.error('图片上传失败，请重试')
  }
}

const insertLink = () => {
  const url = prompt('请输入链接URL:')
  const text = prompt('请输入链接文本:') || url
  if (url) {
    insertText(`[${text}](${url})`)
  }
}

const insertTable = (e: MouseEvent) => {
  e.preventDefault()
  const table = `| 列1 | 列2 | 列3 |
|-----|-----|-----|
| 内容1 | 内容2 | 内容3 |
| 内容4 | 内容5 | 内容6 |`
  insertText(table)
}

const insertBold = (e: MouseEvent) => {
  e.preventDefault()
  insertText('**粗体文字**')
}

const insertItalic = (e: MouseEvent) => {
  e.preventDefault()
  insertText('*斜体文字*')
}

const insertCode = (e: MouseEvent) => {
  e.preventDefault()
  insertText('`代码`')
}

const insertQuote = (e: MouseEvent) => {
  e.preventDefault()
  insertText('> 引用文字')
}

// 文本缩进函数（插入两个全角空格）
const insertTextIndent = (e: MouseEvent) => {
  e.preventDefault()
  // 在当前行的开头插入两个全角空格（用于段落缩进）
  if (textareaRef.value) {
    const start = textareaRef.value.selectionStart
    const end = textareaRef.value.selectionEnd
    const before = content.value.substring(0, start)
    const after = content.value.substring(end)
    
    // 找到当前行的开始位置
    const lineStart = before.lastIndexOf('\n') + 1
    const currentLine = content.value.substring(lineStart, start)
    
    // 在当前行开头插入两个全角空格
    const newContent = content.value.substring(0, lineStart) + 
                      '　　' + 
                      currentLine + 
                      after
    
    content.value = newContent
    emit('update:modelValue', content.value)
    
    // 更新光标位置
    nextTick(() => {
      if (textareaRef.value) {
        const newCursorPos = lineStart + 2 + currentLine.length
        textareaRef.value.setSelectionRange(newCursorPos, newCursorPos)
      }
    })
  }
}

// 移除文本缩进函数
const removeTextIndent = (e: MouseEvent) => {
  e.preventDefault()
  // 删除当前行开头的缩进（全角空格或半角空格）
  if (textareaRef.value) {
    const start = textareaRef.value.selectionStart
    const end = textareaRef.value.selectionEnd
    const before = content.value.substring(0, start)
    const after = content.value.substring(end)
    
    // 找到当前行的开始位置
    const lineStart = before.lastIndexOf('\n') + 1
    const currentLine = content.value.substring(lineStart, start)
    
    let trimmedLine = currentLine
    
    // 删除开头的两个全角空格
    if (trimmedLine.startsWith('　　')) {
      trimmedLine = trimmedLine.substring(2)
    }
    // 或删除开头的4个半角空格
    else if (trimmedLine.startsWith('    ')) {
      trimmedLine = trimmedLine.substring(4)
    }
    
    // 如果有变化，更新内容
    if (trimmedLine !== currentLine) {
      const newContent = content.value.substring(0, lineStart) + 
                        trimmedLine + 
                        after
      content.value = newContent
      emit('update:modelValue', content.value)
      
      // 更新光标位置
      nextTick(() => {
        if (textareaRef.value) {
          const newCursorPos = lineStart + trimmedLine.length
          textareaRef.value.setSelectionRange(newCursorPos, newCursorPos)
        }
      })
    }
  }
}

const insertUnorderedList = (e: MouseEvent) => {
  e.preventDefault()
  insertText('- 列表项1\n- 列表项2\n- 列表项3')
}

const insertOrderedList = (e: MouseEvent) => {
  e.preventDefault()
  insertText('1. 列表项1\n2. 列表项2\n3. 列表项3')
}



const insertText = (text: string) => {
  if (textareaRef.value) {
    const start = textareaRef.value.selectionStart
    const end = textareaRef.value.selectionEnd
    const before = content.value.substring(0, start)
    const after = content.value.substring(end)
    
    // 保存当前滚动位置
    const scrollTop = textareaRef.value.scrollTop
    
    content.value = before + text + after
    
    nextTick(() => {
      if (textareaRef.value) {
        textareaRef.value.focus()
        textareaRef.value.setSelectionRange(start + text.length, start + text.length)
        // 恢复滚动位置
        textareaRef.value.scrollTop = scrollTop
      }
    })
    
    emit('update:modelValue', content.value)
  }
}

// 处理键盘事件
const handleKeyDown = (e: KeyboardEvent) => {
  // 处理 ESC 键退出全屏
  if (e.key === 'Escape' && isFullscreen.value) {
    e.preventDefault()
    isFullscreen.value = false
    return
  }
  
  // 处理 Tab 键，用于缩进
  if (e.key === 'Tab') {
    e.preventDefault()
    
    if (textareaRef.value) {
      const start = textareaRef.value.selectionStart
      const end = textareaRef.value.selectionEnd
      
      // 如果有选中文本，对每一行进行缩进处理
      if (start !== end) {
        // 选中多行的情况
        const before = content.value.substring(0, start)
        const selected = content.value.substring(start, end)
        const after = content.value.substring(end)
        
        // 找到选中文本的第一行和最后一行的起始位置
        const firstLineStart = before.lastIndexOf('\n') + 1
        const lines = selected.split('\n')
        
        // 为每一行添加两个全角空格
        const indentedLines = lines.map(line => '　　' + line).join('\n')
        
        const newContent = content.value.substring(0, firstLineStart) + 
                          indentedLines + 
                          after
        
        content.value = newContent
        emit('update:modelValue', content.value)
        
        // 更新选中区域
        nextTick(() => {
          if (textareaRef.value) {
            const newStart = firstLineStart
            const newEnd = firstLineStart + indentedLines.length
            textareaRef.value.setSelectionRange(newStart, newEnd)
          }
        })
      } else {
        // 没有选中文本，直接插入两个全角空格
        const before = content.value.substring(0, start)
        const after = content.value.substring(end)
        
        content.value = before + '　　' + after
        emit('update:modelValue', content.value)
        
        // 移动光标位置
        nextTick(() => {
          if (textareaRef.value) {
            textareaRef.value.setSelectionRange(start + 2, start + 2)
          }
        })
      }
    }
  }
}

// 处理粘贴事件
const handlePaste = async (e: ClipboardEvent) => {
  const items = e.clipboardData?.items
  if (!items) return
  
  // 查找图片类型的剪贴板项
  for (let i = 0; i < items.length; i++) {
    const item = items[i]
    if (item.type.indexOf('image') !== -1) {
      e.preventDefault() // 阻止默认粘贴行为
      
      const file = item.getAsFile()
      if (file) {
        try {
          const formData = new FormData()
          formData.append('file', file)
          
          const response = await api.post('/posts/upload-image', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          })
          
          if (response.data.url) {
            const imageUrl = response.data.url
            // 直接使用默认描述，用户可以后续修改
            const markdownImage = `![图片描述](${imageUrl})\n`
            
            insertText(markdownImage)
            ElMessage.success('图片上传成功')
          } else {
            ElMessage.error('图片上传失败')
          }
        } catch (error) {
          console.error('图片上传失败:', error)
          ElMessage.error('图片上传失败，请重试')
        }
      }
      break
    }
  }
}

// 生命周期钩子
onMounted(() => {
  if (textareaRef.value) {
    textareaRef.value.addEventListener('paste', handlePaste)
  }
})

onUnmounted(() => {
  if (textareaRef.value) {
    textareaRef.value.removeEventListener('paste', handlePaste)
  }
})

watch(() => props.modelValue, (newValue) => {
  content.value = newValue
})
</script>

<style scoped>
.markdown-editor {
  border: 1px solid #dcdfe6;
  border-radius: 6px;
  overflow: hidden;
}

.editor-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: #f5f7fa;
  border-bottom: 1px solid #dcdfe6;
}

.toolbar-left,
.toolbar-center,
.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.toolbar-center {
  flex: 1;
  justify-content: center;
}

.editor-content {
  position: relative;
  height: 70vh;
  min-height: 500px;
  display: flex;
}

.editor-content.live-preview {
  display: flex;
}

.editor-content.live-preview .editor-panel {
  flex: 1;
  border-right: 1px solid #dcdfe6;
}

.editor-content.live-preview .preview-panel {
  flex: 1;
}

.editor-panel {
  height: 100%;
  width: 100%;
}

.editor-textarea {
  width: 100%;
  height: 100%;
  border: none;
  outline: none;
  padding: 16px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 14px;
  line-height: 1.6;
  resize: none;
  background: white;
  transition: all 0.3s ease;
}

.editor-textarea.drag-over {
  background: rgba(64, 158, 255, 0.05);
  border: 2px dashed #409eff;
}

.drag-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(64, 158, 255, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
  border: 2px dashed #409eff;
  border-radius: 8px;
}

.drag-message {
  text-align: center;
  color: #409eff;
  font-size: 16px;
  font-weight: 500;
}

.drag-message p {
  margin: 8px 0 0 0;
}

.preview-panel {
  height: 100%;
  overflow-y: auto;
  padding: 16px;
  background: white;
}

/* 全屏模式样式 - 占满浏览器可视区域，但不进入浏览器全屏模式 */
.markdown-editor.fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 9999;
  background: white;
  border: none;
  border-radius: 0;
}

.markdown-editor.fullscreen .editor-content {
  height: calc(100vh - 120px); /* 减去工具栏和底部的高度 */
}

.markdown-editor.fullscreen .editor-toolbar {
  border-radius: 0;
  border-left: none;
  border-right: none;
  border-top: none;
}

.markdown-editor.fullscreen .editor-footer {
  border-radius: 0;
  border-left: none;
  border-right: none;
  border-bottom: none;
}

.preview-content {
  max-width: none;
  line-height: 1.7;
  color: #333;
  font-size: 1.1rem;
}

.preview-content :deep(h1),
.preview-content :deep(h2),
.preview-content :deep(h3),
.preview-content :deep(h4),
.preview-content :deep(h5),
.preview-content :deep(h6) {
  margin-top: 24px;
  margin-bottom: 16px;
  font-weight: 600;
  line-height: 1.25;
}

.preview-content :deep(h1) {
  font-size: 1.8em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 8px;
}

.preview-content :deep(h2) {
  font-size: 1.5em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 8px;
}

.preview-content :deep(p) {
  margin-bottom: 16px;
}

.preview-content :deep(blockquote) {
  margin: 0 0 16px 0;
  padding: 0 16px;
  color: #6a737d;
  border-left: 4px solid #dfe2e5;
}

.preview-content :deep(code) {
  padding: 2px 4px;
  background: #f6f8fa;
  border-radius: 3px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 85%;
}

.preview-content :deep(pre) {
  padding: 16px;
  background: #f6f8fa;
  border-radius: 6px;
  overflow: auto;
  margin-bottom: 16px;
}

.preview-content :deep(pre code) {
  padding: 0;
  background: transparent;
}

.preview-content :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 16px;
}

.preview-content :deep(table th),
.preview-content :deep(table td) {
  padding: 8px 12px;
  border: 1px solid #dfe2e5;
}

.preview-content :deep(table th) {
  background: #f6f8fa;
  font-weight: 600;
}

.preview-content :deep(ul),
.preview-content :deep(ol) {
  margin-bottom: 16px;
  padding-left: 24px;
}

.preview-content :deep(li) {
  margin-bottom: 4px;
}

.preview-content :deep(img) {
  max-width: 60%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  margin: 16px auto;
  display: block;
}

.editor-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 8px 12px;
  background: #f5f7fa;
  border-top: 1px solid #dcdfe6;
  font-size: 12px;
  color: #909399;
}

.word-count {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

@media (max-width: 768px) {
  .editor-toolbar {
    flex-direction: column;
    gap: 8px;
  }
  
  .toolbar-left,
  .toolbar-right {
    width: 100%;
    justify-content: center;
  }
  
  .editor-content {
    height: 400px;
  }
}
</style>
